#ifndef __OPENPFEM_H__
#define __OPENPFEM_H__

#include "config.h"

void OpenPFEM_Init(int *argc, char ***argv);
void OpenPFEM_Finalize(void);
void OpenPFEM_Print(const char *fmt, ...);

#if MPI_USE
// 方便检查错误的打印函数，在comm所有进程打印格式为：
//[RANK (进程号)](具体打印信息)
//  comm一般填写MPI_COMM_WORLD或者DEFAULT_COMM就行，会在所有进程打印
void OpenPFEM_RankPrint(MPI_Comm comm, const char *fmt, ...);

/**
 * @brief lhc 2022/8/21 添加: 将MPI_COMM_WORLD分成num_block组
 * @param num_block 分组数
 * @param comm_output 返回num_block个局部通讯域
 * @param myid 返回本进程所在的局部通讯域编号
 * @return
 */
void SplitComm(INT num_block, MPI_Comm **comm_output, INT *myid);

#endif

DOUBLE GetTime();
DOUBLE GetMemory();

///////////////////////////////////////////////////////////////////////////
/*                           helpful operations                          */
///////////////////////////////////////////////////////////////////////////

#define OpenPFEM_Free(POINTER) \
    do                         \
    {                          \
        if ((POINTER) != NULL) \
        {                      \
            free((POINTER));   \
            (POINTER) = NULL;  \
        }                      \
    } while (0)

#define RaiseError(FUNCTION_NAME, ERROR_INFO)                         \
    do                                                                \
    {                                                                 \
        MPI_Barrier(MPI_COMM_WORLD);                                  \
        OpenPFEM_Print("[ERROR %s] %s\n", FUNCTION_NAME, ERROR_INFO); \
        MPI_Abort(MPI_COMM_WORLD, 1);                                 \
    } while (0)

#endif